#include "RingQueue.hpp"

void *cus(void *args)
{
    RingQueue<int> *rq = static_cast<RingQueue<int> *>(args);
    while (true)
    {
        int data = rand() % 10 + 1;
        rq->pop(&data);
        cout << "custom done:" << data << endl;
        sleep(1);
    }
}

void *pro(void *args)
{
    RingQueue<int> *rq = static_cast<RingQueue<int> *>(args);
    while (true)
    {
        int data = rand() % 10 + 1;
        rq->push(data);
        cout << "product done:" << data << endl;
        sleep(1);
    }
}

void single_test() // 单生产者单消费者整型数据
{
    cout << "单生产者单消费者整型数据" << endl;
    srand((time(nullptr)) ^ getpid());
    RingQueue<int> *rq = new RingQueue<int>();
    pthread_t c, p;
    pthread_create(&c, nullptr, cus, rq);
    pthread_create(&p, nullptr, pro, rq);

    pthread_join(c, nullptr);
    pthread_join(p, nullptr);
    delete rq;
}

const char *ops = "+-*/%";
void *cus2(void *args)
{
    RingQueue<Task> *rq = static_cast<RingQueue<Task> *>(args);
    while (true)
    {
        Task t;
        rq->pop(&t);
        t();
        cout << "custom done，处理任务：" << t.formatArg()<<" 结果为："<<t.formatRes() << endl;
        sleep(1);
    }
}

void *pro2(void *args)
{
    RingQueue<Task> *rq = static_cast<RingQueue<Task> *>(args);
    while (true)
    {
        int x = rand() % 100;
        int y = rand() % 100;
        char op = ops[(x + y) % strlen(ops)];
        Task t(x, y, op);
        rq->push(t);
        cout << "product done，产生任务：" << t.formatArg() << endl;
        sleep(1);
    }
}
void many_test()
{
    cout << "多生产者多消费者自定义类型数据" << endl;
    srand((time(nullptr)) ^ getpid());
    RingQueue<Task> *rq = new RingQueue<Task>();
    pthread_t c[5], p[5];
    pthread_create(&c[1], nullptr, cus2, rq);
    pthread_create(&c[2], nullptr, cus2, rq);
    pthread_create(&c[3], nullptr, cus2, rq);
    pthread_create(&c[4], nullptr, cus2, rq);
    pthread_create(&p[1], nullptr, pro2, rq);
    pthread_create(&p[2], nullptr, pro2, rq);
    pthread_create(&p[3], nullptr, pro2, rq);
    pthread_create(&p[4], nullptr, pro2, rq);


    pthread_join(c[1], nullptr);
    pthread_join(c[2], nullptr);
    pthread_join(c[3], nullptr);
    pthread_join(c[4], nullptr);

    pthread_join(p[1], nullptr);
    pthread_join(p[2], nullptr);
    pthread_join(p[3], nullptr);
    pthread_join(p[4], nullptr);

    delete rq;
}

int main()
{
    // single_test();
    many_test();
    return 0;
}